#include "stdlib.h"
#include "string.h"
#include "unistd.h"
#include "MQTTClient.h"

#include "ohos_init.h"
#include "cmsis_os2.h"

#include "wifi_connecter.h"
// Enable or disable SSL/TLS connection (1 for SSL/TLS, 0 for TCP)
#define USE_SSL 0

#if USE_SSL
#define ADDRESS "ssl://aff518f9.ala.cn-hangzhou.emqxsl.cn:8883"
#else
#define ADDRESS "tcp://broker-cn.emqx.io:1883"
#endif

#define USERNAME    "rsu_mqtt"
#define PASSWORD    "123456"
#define CLIENTID    "rsu_client"
#define QOS         0
#define TOPIC       "RSU"
#define TIMEOUT     10000L

#if CHIP_WS63
#define STACK_SIZE 20480
#define MAX_CONNECT_RETRY_TIMES 16
#define CONNECT_ATTEMPT_INTERVAL_MS 300
#else
#define ATTR.STACK_SIZE 10240
#endif

MQTTClient_SSLOptions configureSSLOptions() {
    MQTTClient_SSLOptions ssl_opts = MQTTClient_SSLOptions_initializer;
    ssl_opts.enableServerCertAuth = 0;
    ssl_opts.trustStore = CA_CERTIFICATE_FILE;
    return ssl_opts;
}


void publish(MQTTClient client, char *topic, char *payload) {
    MQTTClient_message message = MQTTClient_message_initializer;
    message.payload = payload;
    message.payloadlen = strlen(payload);
    message.qos = QOS;
    message.retained = 0;
    MQTTClient_deliveryToken token;
    MQTTClient_publishMessage(client, topic, &message, &token);
    MQTTClient_waitForCompletion(client, token, TIMEOUT);
    printf("Send `%s` to topic `%s` \n", payload, TOPIC);
}

int on_message(void *context, char *topicName, int topicLen, MQTTClient_message *message) {
    char *payload = message->payload;
    printf("Received `%s` from `%s` topic \n", payload, topicName);
    MQTTClient_freeMessage(&message);
    MQTTClient_free(topicName);
    return 1;
}


static void MqttTestTask(int *arg)
{
    (void)arg;

    osDelay(10);

    // setup your AP params
    // 设置AP参数，包括SSID、预共享密钥、安全类型（PSK）、netID
    WifiDeviceConfig apConfig = {0};
    if (strcpy_s(apConfig.ssid, sizeof(apConfig.ssid), "MERCURY_lijing24876@")) {
        printf("OK");
    }

    if (strcpy_s(apConfig.preSharedKey, sizeof(apConfig.preSharedKey), "lijing24876@")) {
        printf("OK");
    }

    apConfig.securityType = WIFI_SEC_TYPE_PSK;

#if CHIP_WS63
    int netId = -1;

    // demo启动时，系统的WiFi功能可能没有初始化完毕，需要等待不确定的时候。待优化。
    for (uint8_t i = 0; i < MAX_CONNECT_RETRY_TIMES; i++) {
        osDelay(CONNECT_ATTEMPT_INTERVAL_MS);
        netId = ConnectToHotspot(&apConfig);
        if (netId >= 0) {
            break;
        }
    }
#else
    int netId = ConnectToHotspot(&apConfig);
#endif
    printf("sleep 5s !!\r\n");
    usleep(5000000);


    printf("start mqtt connect !!\r\n");



    int rc;
    MQTTClient client;

    MQTTClient_init();
    MQTTClient_create(&client, ADDRESS, CLIENTID, 0, NULL);
    MQTTClient_connectOptions conn_opts = MQTTClient_connectOptions_initializer;
    // conn_opts.username = USERNAME;
    // conn_opts.password = PASSWORD;

// #if USE_SSL
//     MQTTClient_SSLOptions ssl_opts = configureSSLOptions();
//     conn_opts.ssl = &ssl_opts;
// #endif

    MQTTClient_setCallbacks(client, NULL, NULL, on_message, NULL);
    if ((rc = MQTTClient_connect(client, &conn_opts)) != MQTTCLIENT_SUCCESS) {
        printf("Failed to connect, return code %d\n", rc);
        return;
    } else {
        printf("Connected to MQTT Broker!\n");
    }
    // subscribe topic
    MQTTClient_subscribe(client, TOPIC, QOS);
    printf("MQTTClient_subscribe");
    char payload[16];
    for (int i = 0; i < 10; i += 1) {
        // publish message to broker
        snprintf(payload, 16, "message-%d", i);
        publish(client, TOPIC, payload);
        printf("mqtt sent: %s", payload);
        usleep(1000000);
    }
    MQTTClient_unsubscribe(client, TOPIC);
    MQTTClient_disconnect(client, TIMEOUT);
    MQTTClient_destroy(&client);
    printf("MQTT End!\n");
}

static void MqttTestDemo(void)
{
    osThreadAttr_t attr;

    attr.name = "MqttTestTask";
    attr.attr_bits = 0U;
    attr.cb_mem = NULL;
    attr.cb_size = 0U;
    attr.stack_mem = NULL;
#if CHIP_WS63
    attr.stack_size = STACK_SIZE;
#else
    attr.stack_size = ATTR.STACK_SIZE;
#endif
    attr.priority = osPriorityNormal;

    if (osThreadNew(MqttTestTask, NULL, &attr) == NULL) {
        printf("[MqttTestDemo] Failed to create MqttTestTask!\n");
    }
}

SYS_RUN(MqttTestDemo);